package cn.itcast.erp.service.impl;

import cn.itcast.erp.dao.mapper.CStoreDetailMapper;
import cn.itcast.erp.dao.mapper.CStoreoperMapper;
import cn.itcast.erp.dao.mapper.OrderDetailMapper;
import cn.itcast.erp.dao.mapper.OrdersMapper;
import cn.itcast.erp.entity.*;
import cn.itcast.erp.entity.utils.AjaxResult;
import cn.itcast.erp.service.OrdersService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 采购Service类
 *
 * @author 崔凯铭, 罗宇航
 * @date 2019/6/12
 */

@Service("orders")
public class OrdersServiceImpl implements OrdersService {

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @Resource
    private CStoreDetailMapper cStoreDetailMapper;

    @Resource
    private CStoreoperMapper cStoreoperMapper;

    @Override
    public AjaxResult findOrders(Orders orders) {

        AjaxResult ar = new AjaxResult();
        int total = ordersMapper.count(orders);
        List<Orders> rows = ordersMapper.findOrders(orders);
        ar.setTotal(total);
        ar.setRows(rows);
        return ar;
    }

    @Transactional
    @Override
    public int insertOrders(Orders orders, Emp emp) {
        Double sum = 0.00;
        for (Orderdetail orderDetail : orders.getOrderDetails()) {
            sum = sum + orderDetail.getMoney();
        }
        UUID num = UUID.randomUUID();
        String s = num.toString();
        orders.setWaybillsn(s);
        BigDecimal bigDecimal = new BigDecimal(sum);
        double value = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        orders.setTotalmoney(value);
        orders.setCreater(emp.getUuid());
        orders.setState(Orders.STATE_CREATE);
        Date date = new Date();
        orders.setCreatetime(date);
        int i = this.ordersMapper.insertOrders(orders);
        for (Orderdetail orderDetail : orders.getOrderDetails()) {
            orderDetail.setState(Orderdetail.STATE_NOT_IN);
            orderDetail.setOrdersuuid(orders.getUuid());
        }
        this.orderDetailMapper.insertOrderDetail(orders.getOrderDetails());
        return i;
    }

    @Override
    public Orders findOrderByUuid(Orders orders) {
        Orders order = this.ordersMapper.findOrderByUuid(orders);
        return order;
    }

    @Override
    public int checkOrder(Orders orders, Emp emp) {
        orders.setType(Orders.TYPE_IN);
        orders.setState(Orders.STATE_CREATE);
        Orders orderByUuid = this.ordersMapper.findOrderByUuid(orders);
        Date date = new Date();
        orderByUuid.setChecktime(date);
        orderByUuid.setState(Orders.STATE_CHECK);
        orderByUuid.setChecker(emp.getUuid());
        int i = this.ordersMapper.updateOrder(orderByUuid);
        if (i > 0) {
            return i;
        }
        return -1;
    }

    @Override
    public int startOrder(Orders orders, Emp emp) {
        orders.setType(Orders.TYPE_IN);
        orders.setState(Orders.STATE_CHECK);
        Orders orderByUuid = this.ordersMapper.findOrderByUuid(orders);
        Date date = new Date();
        orderByUuid.setStarttime(date);
        orderByUuid.setState(Orders.STATE_START);
        orderByUuid.setStarter(emp.getUuid());
        int i = this.ordersMapper.updateOrder(orderByUuid);
        if (i > 0) {
            return i;
        }
        return -1;
    }

    @Transactional
    @Override
    public AjaxResult inStore(Orderdetail orderdetail, Emp emp) {
        AjaxResult ar = new AjaxResult();
        Orderdetail orderDetailByUuid = this.orderDetailMapper.findOrderDetailByUuid(orderdetail);
        if (Orderdetail.STATE_IN.equals(orderDetailByUuid.getState())) {
            ar.setMsg("不能重复入库");
            return ar;
        }
        Date date = new Date();
        Long storeuuid = orderdetail.getStoreuuid();
        orderDetailByUuid.setEndtime(date);
        orderDetailByUuid.setStoreuuid(storeuuid);
        orderDetailByUuid.setState(Orderdetail.STATE_IN);
        orderDetailByUuid.setEnder(emp.getUuid());
        this.orderDetailMapper.updateOrderDetail(orderDetailByUuid);
        Long ordersuuid = orderDetailByUuid.getOrdersuuid();
        boolean inStore = this.orderDetailMapper.isInStore(ordersuuid);
        if (inStore) {
            Orders oneOrder = this.ordersMapper.findOneOrder(ordersuuid);
            oneOrder.setState(Orders.STATE_END);
            oneOrder.setEndtime(date);
            oneOrder.setEnder(emp.getUuid());
            this.ordersMapper.updateOrder(oneOrder);
        }

        // 添加库存详情表数据
        Long goodsuuid = orderDetailByUuid.getGoodsuuid();
        Storedetail storedetail = this.cStoreDetailMapper.findOneDetail(storeuuid, goodsuuid);
        if (storedetail != null) {
            // 如果之前该仓库中存储过该商品
            Long num = storedetail.getNum();
            storedetail.setNum(num + orderDetailByUuid.getNum());
            this.cStoreDetailMapper.updateOne(storedetail);
        } else {
            // 如果该仓库从未存储过该商品
            storedetail = new Storedetail();
            storedetail.setStoreuuid(storeuuid);
            storedetail.setGoodsuuid(goodsuuid);
            storedetail.setNum(orderDetailByUuid.getNum());
            this.cStoreDetailMapper.insertOne(storedetail);
        }
        // 库存变动记录
        Storeoper oper = new Storeoper();
        oper.setEmpuuid(emp.getUuid());
        oper.setOpertime(date);
        oper.setStoreuuid(storeuuid);
        oper.setGoodsuuid(goodsuuid);
        oper.setNum(orderDetailByUuid.getNum());
        oper.setType(Storeoper.TYPE_IN);
        this.cStoreoperMapper.insertOne(oper);
        ar.setMsg("入库成功");
        return ar;
    }

    //销售出库
    @Transactional
    @Override
    public AjaxResult outStore(Orderdetail orderdetail, Emp emp) {
        AjaxResult ar = new AjaxResult();
        Orderdetail orderDetailByUuid = this.orderDetailMapper.findOrderDetailByUuid(orderdetail);
        if (Orderdetail.STATE_OUT.equals(orderDetailByUuid.getState())) {
            ar.setMsg("不能重复出库");
            return ar;
        }
        Date date = new Date();
        Long storeuuid = orderdetail.getStoreuuid();
        orderDetailByUuid.setEndtime(date);
        orderDetailByUuid.setStoreuuid(storeuuid);
        orderDetailByUuid.setState(Orderdetail.STATE_OUT);
        orderDetailByUuid.setEnder(emp.getUuid());
        Long goodsuuid = orderDetailByUuid.getGoodsuuid();
        Storedetail storedetail = this.cStoreDetailMapper.findOneDetail(storeuuid, goodsuuid);
        if (storedetail == null) {
            ar.setMsg("仓库下没有此商品");
            return ar;
        }
        if (storedetail.getNum() < orderDetailByUuid.getNum()) {
            ar.setMsg("仓库库存不足");
            return ar;
        }
        //减少库存
        storedetail.setNum(storedetail.getNum() - orderDetailByUuid.getNum());
        this.cStoreDetailMapper.updateOne(storedetail);

        //库存变动记录
        Storeoper oper = new Storeoper();
        oper.setEmpuuid(emp.getUuid());
        oper.setOpertime(date);
        oper.setStoreuuid(storeuuid);
        oper.setGoodsuuid(goodsuuid);
        oper.setNum(orderDetailByUuid.getNum());
        oper.setType(Storeoper.TYPE_OUT);
        this.cStoreoperMapper.insertOne(oper);

        // 更新该订单详情的状态为已出库
        orderDetailByUuid.setEnder(emp.getUuid());
        orderDetailByUuid.setEndtime(date);
        orderDetailByUuid.setState(Orderdetail.STATE_OUT);
        this.orderDetailMapper.updateOrderDetail(orderDetailByUuid);

        // 检查是否所有商品都已出库
        boolean outStore = this.orderDetailMapper.isInStore(orderDetailByUuid.getOrdersuuid());
        if (outStore) {
            Orders order = this.ordersMapper.findOneOrder(orderDetailByUuid.getOrdersuuid());
            order.setEndtime(date);
            order.setEnder(emp.getUuid());
            order.setState(Orders.STATE_OUT);
            this.ordersMapper.updateOrder(order);
        }
        ar.setMsg("出库成功");
        return ar;
    }
}
